home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Turnbull China Bikeride
/
Turnbull China Bikeride - Disc 2.iso
/
STUTTGART
/
FROMUTS
/
DDEPASCAL
/
DDE
/
!PC
/
README
< prev
next >
Wrap
Text File
|
1992-05-05
|
40KB
|
1,173 lines
Introduction
============
!PC is an ISO Level 1 Pascal compiler. It is designed to be used with
the desktop development environment supplied with Desktop C. It may
be used to generate RISC OS desktop applications or relocatable
modules written in Pascal.
The Pascal compiler contains a number of language extensions to
overcome limitations in the ISO Pascal standard and to allow RISC OS
applications to be written in Pascal.
A set of header files is provided which allow Pascal programs to be
linked with the RISC_OSLib library provided with Desktop C.
The Pascal run time library is provided in two variants, one for
linking applications and the second for linking modules. The Pascal
run time library calls the C library so programs written in Pascal
must be linked with either the unshared library ANSILib or the shared
library Stubs.
An example desktop program !Balls64 is included. This is a conversion
of the !Balls64 program provided with Desktop C.
Installation
------------
To install !PC to a hard disc simply copy the !PC directory into the
DDE directory on your hard disc.
Copy the following lines to your !Make.choices.tools file in the DDE
directory.
------------------------------------
PC
p
-c -depend !Depend -throwback -IP:
pc $(pcflags) -o $@ $<
DDE:!PC.desc
DDE:!PC.!setup
------------------------------------
Installing for command line use
-------------------------------
If you wish to use the Pascal compiler from the command line
copy/rename the file !PC.PC to your library directory and add the
following line to your !Boot.
%Obey <DDE directory>.!PC.!Boot
Where <DDE directory> is substituted with the full pathname of your
DDE directory. This sets up the variables P$LibRoot and P$Path which
are used by the Pascal compiler to locate the pascal library and the
RISC_OSLib Pascal headers.
Using the Pascal compiler from the command line is described in the
section "The command line".
Using !PC
=========
To start !PC double click on the !PC application. This will place the
!PC icon on the icon bar.
Click Select on the !PC icon, this will open a setup dialog box
containing a single writeable icon labelled "Source:", a number
of option icons and two action icons labelled "Run" and "Cancel".
To compile a Pascal program drag the Pascal source to the Source
icon and click Run. Note the Pascal source must be stored in a
directory called "p", this is to allow !Make to differentiate between
C and Pascal sources.
If the program compiles successfully a "Save" dialog box will be
displayed containing an icon representing the compiled image. Drag
this to a directory viewer and run it by double clicking on it.
If errors are encountered in the source the errors will be listed in a
window. If you are using the editor !SrcEdit and the "Throwback"
option is enabled the errors will also be displayed in a "Throwback"
window. Double clicking on an error in the Throwback will cause
!SrcEdit to open the source file containing the error at the line
which generated the error, this line will be highlighted for clarity.
If you have more than one source file to compile drag all the source
files to the "Source" icon and click Run. All the source files will
be compiled in turn and then linked together to produce a single
executable. Note: standard Pascal does not allow you to write your
programs in separate source units, !PC allows this by means of
language extensions described in the section "Language extensions".
Setup dialog box options
------------------------
Compile only:
Usually when !PC is used to compile a Pascal program it automatically
runs the linker to bind your program with the Pascal run time library.
This option can be used to prevent the link step from happening. You
may want to do this if you have a number of Pascal sources which you
wish to compile separately. You should place such files in a
directory called "o" so that !PC and !Make can differentiate between
pre-compiled object files and source files.
To link object files generated this way drag the object files to the
Source icon and click Run. !PC will notice that they are pre-compiled
object files (because they are stored in the "o" directory) and will
just perform the necessary link step. (You can drag any mixture of
source and object file in, !PC will perform the appropriate action
on each and then link them all).
Assembler output:
Use this option if you wish to examine the assembler code generated
by the compiler.
ISO:
If this option is enabled !PC will compile strictly according to the
Pascal standard as described in BS 6192 : 1982.
Debug:
If this option is enabled !PC will generate an image suitable for
use with the desktop debugger !DDT. The debugging facilities provided
by DDT are limited in certain ways when debugging Pascal programs,
these limitations and debugging in general are described in the
section "Pascal and DDT".
Throwback:
If this option is enabled and the editor !SrcEdit is loaded errors
in compilation are listed in a Throwback window. This window can
be use to rapidly locate and correct errors in your program.
This option is enabled by default.
Uses RISC_OSLib:
This option should be selected if your pascal program makes any calls
to RISC_OSLib library functions. It cause the compiler to instruct the
linker to include RISC_OSLib in the list of libraries to be searched.
Run time checks:
These options enable or disable the generation of run time checking
code which is inserted in the generated code. When developing
a program you will probably wish to leave all these options enabled.
For the final compilation, however, you may wish to disable some or
all of the run time checks to reduce code size and improve
performance.
Array bounds:
This option inserts code to check that array accesses do not exceed
their array bounds.
Nil pointers:
This option inserts code to check that Nil pointers are not
dereferenced.
Variable references:
This option inserts code to check that variables are assigned before
being referenced.
Assertion statements:
One of the language extensions described in the section "Language
extensions" is an "assert" statement which allows you to insert
your own checks in your code. If this option is enabled the compiler
will compile these assert statements. If the option is disabled such
statements will not be compiled and no extra code will be generated.
Setup menu options
------------------
Other less commonly used options may be accessed from the menu
on the setup dialog box. These options are as follows.
Command line:
This option allows you to examine and/or change the command line
generated by the !PC frontend which is used to run the Pascal
compiler. When you change the command line and wish to execute the
changed command click on the Run icon in the Command line dialog box.
Once you move off the Command line dialog box onto the setup menu
the changed command line will be forgotten and the original command
line (as constructed by the !PC tool) will be reconstructed.
No warnings:
Supresses the generation of warning messages.
Module code:
This options must be enabled when compiling code to be used to
generate a RISC OS relocatable module using the CMHG tool. For
more information on writing relocatable modules in Pascal refer
to the section "Writing relocatable modules in Pascal"
Profile:
This option enables the generation of code which is suitable for
use with the ANSILib functions _mapstore and _fmapstore. This
code counts the number of times each function or block of code
is executed. _mapstore and _fmapstore output the profiling
information to the screen or to a named file respectively. For
details on how to call _mapstore or _fmapstore from Pascal refer
to the section "Language extensions".
Preprocess only:
The compiler uses a pre-processor (similar to the C pre-processor)
before performing the actual compilation. This option disables the
compilation and just runs the pre-processor on the source file. The
pre-processed output is displayed in the compilation window.
Include:
When searching for "include" files (described in the section
"Language extension") the compiler usually search the path P:
(ie the setting of the variable P$Path). You can use this option
to change where the compiler searches for header files.
Keep comments:
Normally when pre-processing the compiler removes any comments in
the source code. If this option is enabled the pre-processor will
not remove comments.
Libraries:
This option specifies a list of libraries to be searched when linking.
These libraries are in addition to the default Pascal run time
library ("P:o.PLib"). By default this option is set to
"C:o.RISC_OSLib,C:o.stubs".
Pascal programs must be linked with the C library as the Pascal run
time library calls the C library. By default they are linked with
the shared library Stubs. You can change this using this option to
link with the unshared ANSILib instead, if, for example you wish to
use the _mapstore or _fmapstore functions which are not included in
shared library or if you wish to use the overlay manager in the
unshared library.
Predefine:
The pre-processor allows you to define symbols which can be used to
conditionally compile sections of code. The use of pre-processor
symbols is described in the section "Language extensions". You may
wish to use this option if, for example, you have code which displays
debugging information which you would not normally wish to have
compiled unless you are trying to debug the program.
Undefine:
The compiler automatically defines some pre-processor symbols on
startup. These symbols are listed in the section "Language
extensions". This option allows you to undefine any or all of
the symbols.
Work directory:
This option allows you to change the "Work directory" used by !PC.
The concept of a work directory is explained in the section
"File naming and placing" in the Desktop C manual.
Other:
This allows you to specify other options to the underlying command
line compiler. These options have not been included in the setup
dialog because they are obscure and rarely used. A list of these
options is given in the section "The command line".
Language extensions
===================
Identifiers
Identifiers may start with and contain underscores. There is no limit
on identifier length and all characters are significant.
Files
Input and output need not appear in the program header. `File of char'
and `packed file of char' are treated as equivalent to `text'. Lazy
evaluation is performed on files opened for input. In the absence of
explicit file bindings (see reset and rewrite in the section on
library extensions) external files are bound to a filename
corresponding to the file identifier in the current directory, input
and output are bound to the equivalent of C stdin and stdout streams
(normally the keyboard and screen). Files are buffered, on a read
request from input the output buffer is flushed.
Strings
Strings are blank padded or truncated in expressions and as value
parameters to fit the required size. Strings may be of length 1. The
null string '' is permitted. The packed attribute may be omitted in a
string declaration.
Pascal strings are zero terminated, the compiler adds one byte to the
allocation space of the string and initialises this byte to zero when
the string is assigned. Thus Pascal strings may be used in calls to
external functions written in C.
The predefined type string is equivalent to the C `char *' and may be
used in external calls to C. Variables of type string are compatible
with Pascal strings and may be used in assignments and expressions and
as value parameters. Note that no space is allocated for a variable of
type string, space must be allocated either by assignment or by
explicit allocation using, for example, malloc.
The predefined type alpha = packed array[1..10] of char is intended
for use with the extended Pascal library, for example, date and time.
See the section on library extensions.
Procedures and functions
Procedures may return values, these are declared like functions with
the keyword procedure substituted for function. Value returning
procedures may be called in a procedure or function context. This is
intended for use with external functions which return error codes
which are not generally checked, for example, putchar.
Procedures and functions may return records, like pointers these may
not be immediatly referenced but must be assigned to a variable.
Variadic functions may be declared by placing a .. as the last
parameter. Variadic arguments may be accessed using the address and
size functions (see the section on library extensions) however the
intended purpose is for declaring external variadic functions, for
example, printf.
Procedure and functions pointers may be declared, these are declared
by placing a `^' before a procedure or function declaration in a type
declaration, note that the procedure or function must be given a name
and all parameters must be named. Only top level and external
procedures or functions may be be assigned to a procedure or function
pointer. Procedure and function pointers are intended for use with
external procedures or functions which take or return procedure or
function pointers, for example, signal.
External objects
Procedures, functions and variables may be declared external or global
by placing extern; or external; after the declaration (like forward is
used for declaring forward referenced procedures or functions). Such
objects are taken to be external if there is no definition of the
object in the same module and global if there is a definition. Objects
declared external use the case of the external declaration identifier.
External declarations are case sensitive between modules and case
insensitive within a single module. The program heading may be omitted
to create a module containing only procedure and functions and/or
variables. No mainline may be given if the program heading is omitted.
The recommended way to use external declarations is to create a header
file (ending with `.h') containing the external declarations and use
the #include mechanism provided by the C preprocessor to include this
header in both the module defining the object and the module
referencing the object. This insures type correctness between modules.
Note that the filename after the #include must be enclosed in double
quotes not single quotes.
Type casts
For each pointer, ordinal or file type declared a cast function of the
same name is automatically declared which casts a pointer, ordinal or
file variable to the declared type.
Constants
Constant expressions may be used in const declarations. The following
functions may be used in constant expressions if they have constant
arguments: shl, shr, uand, uor, uxor, unot, trunc, ord, chr, succ,
pred, odd, and undefined.
Declarations
Multiple Label, Const, Type and Variable declarations sections may be
given within a single block. Label, Const, Type, Variable, Procedure
and Function declarations may occur in any order.
Predefined types
string = ^char - This type is compatible with Pascal strings and is
intended for use with with external library functions which require a
C style string.
alpha = packed array[1..10] of char - This type is used with the
extended library functions time and date.
pointer - This is a generic pointer type compatible with all other
pointer types. It is equivalent to the C void * type.
byte - This is a one byte long signed integer type.
short - This is a half word long signed integer type.
word - This is a word long unsigned integer type.
error - Variables of this type may be used to hold pointers to RISC OS
errors. These variables are compatible with the with the Pascal type
boolean yielding True if the variable points to RISC OS error block.
Operators
The additional operators `&' and `|' are provided. These are
functionally identical to and and or.
Preprocessor
------------
The Pascal compiler invokes the C preprocessor on the Pascal source
before compiling it. A complete description of the C preprocessor
is not given here.
#include "<header>.h"
This reads a header file "h.<header>" into your Pascal source. Header
files are used to contain inter module definitions when writing
multiple module Pascal programs. A standard set of headers is provided
for use with modules in the library RISC_OSLib. See the example
program !Balls64 for examples of how to use RISC_OSLib.
Header files are searched for first in the current directory, then in
the directory <P$LibRoot>. By default <P$LibRoot> is set to P:. This
causes the compiler to search the directory specified by the comma
separated list of directories in P$Path. This is set up by the !PC
application to point to the directory containing the RISC_OSLib
headers.
#define <symbol> [<expansion>]
This defines a simple symbol expansion. The <symbol> is replaced with
its expansion when it occurs in your source. If <expansion> is omitted
the following default is used.
#define <symbol> 1
#define <macro>(<arg1>, <arg2>, ...) <macro expansion>
This defines a macro expansion. When a function or procedure call is
made which corresponds to the macro definition the macro is expanded.
Arguments <arg1>, <arg2>, ... are replaced where they occur in the
macro expansion.
#undef <symbol>|<macro>
Removes a symbol or macro definition.
#ifdef <symbol>
#else
#endif
This construct may be used to conditionally compile section of code.
If the preprocessor symbol <symbol> is defined the code between
the #ifdef <symbol> and the #else is compiled, otherwise the code
between the #else and the #endif is compiled. The #else clause may
be omitted.
The use of the C preprocess #if is not supported.
#error <text of error>
Causes compilation to stop printing <text of error>. This may be
used when conditionally compiling code for different architectures or
operating systems, for example,
#ifdef BIG_ENDIAN
#error This code must be modified to run on a big endian machine
#endif
#pragma -<letter>[<digit>]
#pragma [no_]<pragma>
Pragmas may be specified in two forms, a long form and a short form.
The following pragmas are recognised.
long form short form negative short form
--------- ---------- -------------------
check_memory_accesses -c1 -c0
continue_after_hash_error -e1 -e0
profile -p1 -p0
check_stack -s0 -s1
check_memory_accesses (default = off)
This tells the compiler to insert code to check that memory accesses
(via pointers or arrays) are within the application space allocated
to the application.
continue_after_hash_error (default = off)
This tells the compiler to continue compilation after it encounters
a #error statement.
profile (default = off)
This pragma tells the compiler to insert code to count the number of
times each procedure or function is called. To display the count
insert a call to _mapstore or _fmapstore at the end of your program.
check_stack (default = on)
This pragma tells the compiler to insert code to check that the stack
limit has not been exceeded in each procedure / function entry. The
code checks that the procedure / function has enough stack to execute
to completion and will try to extend the stack if this is not the
case.
check_stack must be disabled around signal handlers which deal with
stack overflow.
Library extensions
------------------
address(x) : pointer
Returns the address of variable access x.
argc : integer
Returns the number of command line arguments to the program including
the program name (ie argc is always at least 1).
argv(i, a)
where i is an integer expression in range 0 to argc and a is a string
variable. If a is of type string then the C expression argv[i] is
assigned directly to a (ie a will point directly into the argv array
and should not therefore be modified otherwise the contents of argv[i]
are copied (possibly blank padded or truncated) to a.
assert(x[, a])
where x is a boolean expressions and a is an optional string
expression (typically explaining why the assertion might have failed).
The assert call checks the value of x and if it is false generates a
run time error giving the file and line number where the assertion
failed. The reason string a is also printed if given in the assert
call. Calls to the assert function must be enabled with the -rp option
on the command line.
byte_offset(t, f) : integer
t is the name of a record type, f is the name of a field within that
record. Returns the offset (in bytes) of field f within a variable of
record type t.
card(s) : integer
where s is a set expression returns the number of elements in s.
close(f)
where f is a file variable close the file bound to f, deallocates all
buffers associated with f and frees f for reallocation.
clock : integer
returns the number of milliseconds elapsed since this program started.
date(a)
where a is a variable of type alpha assigns the current date to a in
the form `dd mmm yy'.
flush(f)
flushes any output buffered for file f into its associated file
binding.
halt
stops execution and returns control to the parent process with a
return code of 0.
iaddress(x) : integer
Returns the address of variable access x as an integer. This is
equivalent to integer(address(x)).
ignore(x)
where x is an expression of any type. Does nothing.
linelimit(f, x)
where f is a variable of type text and x is and integer expression.
Limits the number of lines of output to file f to x. If x is less than
0 no limit is imposed. By default no limit is imposed. These limits
are ignored by the current release.
message(...)
This is equivalent to writeln(...) except it writes to the unbuffered
error stream stderr.
null
Does nothing.
random(x) : real
where x is a real expression which is evaluated but otherwise ignored
returns a random number between 0.0 and 1.0 inclusive. random uses a
linear congruential random number generator. Successive seeds are
generated as (seed * 62605 + 113218009) mod 536870912. The initial
seed is 7774755. The `random' numbers generated by this method are not
very random, the preferred method is to use the external function
rand.
read(..., a, ...)
readln(..., a, ...)
where a is a string variable reads the remainder of the text line into
a. The text line is blank padded or truncated to fit the string. If
the variable is of type string it is assumed that it is pointing to an
allocated area large enough to hold the current line.
remove(a)
where a is a string expression removes the file whose name is a
(with trailing blanks removed).
reset(f, a)
where f is a file variable and a is a string expression associates the
filename f with the file variable and opens that file for reading.
Note that there is no way of detecting an error opening a file (eg.
file not found). To do this use the external function fopen.
rewrite(f, a)
Similarly to reset, the two argument form of rewrite allows a filename
to be bound to a file variable except the file is opened for writing
instead of reading.
seed(x) : integer
where x is an integer expression sets the current random number
generator seed to x and returns the value of the previous seed.
shl(x1, x2) : integer
where x1 and x2 are integers returns x1 shifted left x2 times. This is
equivalent to x1 << x2 in C.
shr(x1, x2) : integer
where x1 and x2 are integers returns x1 shifted right x2 times. This
is equivalent to x1 >> x2 in C.
size(x) : integer
where x is a variable access returns the size of variable access x in
bytes.
stlimit(x)
where x is an integer expression limits the number of statements that
may be executed by the current program. By default no limit is
imposed. This limit is ignored by the current release.
swi(<swi-no> [ , <inregset> { , <inarg> } ]
[ ; <outregset> { , <outarg> } ] [ ; <returnreg> ]) : integer
swix(<swi-no> [ , <inregset> { , <inarg> } ]
[ ; <outregset> { , <outarg> } ]) : error
calls a RISC OS SWI. swix calls the X form of the SWI, swi calls the
non X form.
<swi-no> is an integer expression specifying the SWI no.,
alternatively <swi-no> may be a constant string literal specifying the
name of the SWI to be called, this name is looked up by the compiler
at compile time and converted into the SWI no.
<inregset> is a constant register set specifying the input registers
for the SWI.
Each <inarg> argument corresponds to one set element in the <inregset>
from low numbered registers to high numbered registers. Each argument
must be less than or equal to a machine word in size. If an array,
record or string is specified as an input register the address is
taken and passed to the SWI.
<outregset> is a constant register set specifying the output registers
for the SWI.
Each <outarg> argument corresponds to one set element in the
<outregset> from low numbered registers to high numbered registers.
Each argument must be equal to a machine word in size (the compiler
will pad some arguments less than a word in size to a word size).
<returnreg> specifies a register to be returned from the swi function
call. If this is not specified R0 is returned by default.
swix returns type error. This is a pointer to a system error, this is
set to the Nil pointer if there was no error. The type error may be
used in boolean expressions yielding True if it points to an error
block.
Eg:
e = swix('Wimp_Initialise', [0,1,2], 200, $4b534154, 'Test';
[1], task_handle);
sysclock : integer
returns the number of milliseconds elapsed since this program started.
time(a)
where a is a variable of type alpha assigns the current local time to
a in the form `hh:mm:ss'.
uand(x1, x2) : integer
where x1 and x2 are integer returns the bitwise and of x1 and x2. This
is equivalent to x1 & x2
uor(x1, x2) : integer
where x1 and x2 are integer returns the bitwise or of x1 and x2. This
is equivalent to x1 | x2 in C.
undefined(x) : boolean
where x is a real expression returns false.
unot(x) : integer
where x is integer returns the bitwise negation of x. This is
equivalent to ~x in C.
uxor(x1, x2) : integer
where x1 and x2 are integer returns the bitwise exclusive or of x1 and
x2. This is equivalent to x1 ^ x2 in C.
write(..., x [: n] <mode>, ...)
writeln(..., x [: n] <mode>, ...)
where x is a boolean, character or integer expression, n is an
optional field width and <mode> is one of hex or oct writes the
expression x in hexadecimal or octal notation respectively.
wallclock : integer
returns the time in seconds since 00:00:00 GMT, January 1, 1970.
The command line
================
The syntax of the Pascal command line is:
*pc [options] filenames
The following options are available
-iso
Compile strictly according to the ISO Pascal standard (equivalent to
BS 6192 : 1982).
-c
Do not perform the Link step. This merely compiles the source
program(s), leaving the object file(s) in the o directory.
-E
If this flag is specified, only the preprocessor phase of the compiler
is executed. The output from this phase is sent to the standard output
stream. This may be redirected to a file by using the command line
output redirection. For example:
pc -E myprog > ppoutput
-C
When used in conjunction with the -E option this option specifies
that comments should be included in the pre-processor output.
-D<symbol>
This option may be used to define a preprocessor symbol. These symbols
may be used to conditionally compile sections of code using the #ifdef
or #ifndef preprocessor constructs. The pre-processor is described in
the section "Language extensions".
-U
This option may be used to undefine certain symbols which are defined
automatically by the compiler, for example the symbol "__arm".
-w
Supresses the generation of warning messages
-s
If this flag is specified, no object code is generated. Instead an
assembly listing of the code produced is written to s.<file>.
-g
Generate debugging tables suitable for use with the desktop debugger
DDT. Object files with debugging tables must be linked with the -debug
option to be usable with the debugger.
-r<mod>
Enables a selction of run time checks. Enabling these checks may add
considerably to the size and speed of execution of the generated code
so they should be left disabled for production software. Multiple
modifiers may be specified after the -r, for example, -rarnp will
enable all run time checking.
-ra
This options turns on array bound checking, if an array bound is
exceeded during execution the error "Array index out of bounds" will
be generated. Use the debugger to determine the location of the error.
-rn
Turns on Nil pointer checking. If a Nil pointer is referenced during
execution the error "Uninitialised variable or Nil pointer referenced"
will be generated. Use the debugger to determine the location of the
error.
-rr
Turns on uninitialised variable checking. If an uninitialised variable
reference is detected during execution the error "Uninitialised
variable or Nil pointer referenced" will be generated. Use the
debugger to determine the location of the error.
-rp
Enables the generation of code for assertion statements embedded in
the code. If an assertion statement fails the message "*** assertion
failed: <diagnostic string>, file <file>, line <line>" will be written
to the standard error stream followed by a postmortem backtrace. If
you are running the program from within the desktop you will need to
redirect the standard error stream to a file to prevent the output
being written to the graphics screen. To do this use the command line
redirection facility, for example, "Run <Prog$Dir>.!Runimage
2><Prog$Dir>.ErrOutput".
-ff
Do not embed function names in the code area. The compiler does this
to make the output produced by the stack backtrace function and
_mapstore() more readable. Removing the names makes the code slightly
smaller (typically 5%) at the expense of less meangingful backtraces
and _mapstore() outputs.
-fw
Allow string literals to be writeable, as expected by some older UNIX
code, by allocating them in the program's data area rather than the
notionally read-only area.
You will need to use this option if you are generating code for use
with the overlay manager.
-p
Generate code suitable for use with the _mapstore() and _fmapstore
profiling functions in ANSILib
-zp<mod>
This option can be used to select one of the #pragma directives over
a complete source module. These are described in the section on the
preprocessor.
For example the option -zps1 would disable stack checking in all the
functions in the source module being compiled.
Other options
-------------
Other unrecognised options will be passed through to the linker. For
example the -o <filename> which is used to specify the name of the
image to be generated and the -l <libraries> which may be used to
specify a comma separated list of libraries to be included in the link
step.
Pascal and DDT
==============
To prepare a program for use with DDT specify the "Debug" option in
the compiler and linker setup dialog boxes or the -g and -debug
options on the compiler and linkers command line respectively.
If you are using the compiler to perform the link step you do not need
to specify the debug option to the linker. The compiler will specify
this when it invokes the linker.
The Pascal compiler creates a pseudo procedure 'main' which
corresponds to the start of the Pascal program. DDT automatically sets
a breakpoint on 'main' when it starts so just selecting continue in
DDT will continue execution (through the library initialisation) until
it reaches the start of your source code and then stop and display
your source code.
You can display Pascal variables but there are some limitations.
Global Pascal variables are not available to the debugger, local
variables and procedure/function arguments are. If this causes
problems you can wrap your entire program up in a single procedure and
have a simple mainline which just calls this procedure. This has the
effect of making all global variable local to the procedure and hence
accessible by the debugger.
When entering expressions in the debugger they must be entered using C
syntax as this is the only syntax the debugger understands. When the
debugger displays expressions it will display them in C style syntax.
Procedures are named as <proc>.<subproc>.<subsubproc>... Procedure
procb in the following would be referred to as proca.procb.
Procedure proca;
Procedure procb;
...
Data representation
===================
This section describes how pascal objects (records, arrays etc) are
represented at the machine level. This information is required if you
are writing code which calls or is called by code written in other
languages (for example, C or assembler).
The Pascal compiler uses the APCS-R variant of the ARM Procedure Call
Standard. This has the following register bindings. The ARM Procedure
Call Standard is not described here. It is described in the C Release
3 and Desktop Development Environment manuals.
sl RN 10
fp RN 11
ip RN 12
sp RN 13
These are the same bindings as those used by C Release 3 and C Release
4. C Release 2 and ForTran 77 use different register bindings so code
compiled using these compilers cannot easily be interworked with
Pascal.
The following describes the machine representation for each pascal
type.
Simple types:
-------------
Integer
-------
Integers and subranges of integers are stored as words (32 bits).
These are always word aligned. The compiler will insert padding in
records to ensure this. On function entry integer arguments may be
stored in registers 0 to 3.
This is compatible with the C type 'int'.
Real
----
Reals are stored as two words, word aligned. On function entry a real
may occupy 2 of the registers 0 to 3.
This is compatible with the C type 'double'.
Char
----
Chars and subranges of chars are stored as single bytes. On function
entry these may be stored (0 extended) in registers 0 to 3. Chars
which are not part of an array or record are stored in words (the
unused bytes in the word are 0 padded).
Care must be taken when passing a char which is an element of an array
or record by address or by reference to an external function written
in another language. You must ensure that the external function does
not write back a full word. If this is the case it may overwrite other
elements of the array or record. In this case use a Char which is not
an element of an array or record and assign it into the array or
record when the procedure / function returns.
Boolean
-------
Booleans and subranges of booleans are stored as single bytes. False
has the ordinal value 0, True has the ordinal value 1. On function
entry these may be stored (0 extended) in registers 0 to 3. Booleans
which are not part of an array or record are stored in words (the
unused bytes in the word are 0 padded).
Similar care must be taken when passing Booleans which are elements of
arrays or records to functions by address or reference.
Text
----
This uses the same representation as the compound type File of Char.
Compound types:
---------------
Compound types are stored at word aligned addresses, no distinction is
made between packed and unpacked types.
The storage of conformant array formal parameters and procedure or
function formal parameters is not described here.
Records
-------
Element of records are stored at monotonically increasing addresses
within the record. These addresses are padded as necessary to fit the
alignment constraints of the record elements.
For variant records the maximum space is allocated to allow storage of
any variant in the variant part. If a variant descriminator is present
this is stored after all other elements of the record and before the
variant part.
Arrays
------
Elements of arrays are stored at monotonically increasing addresses
within the array. For arrays of char an extra byte is allocated to the
storage size of the array, this byte is initialised to 0. This allows
Pascal arrays of char to be used in system and C library calls which
require 0 terminated strings.
Sets
----
Sets are stored as bit images, each bit corresponding to one element
of the set (1 => element is present). Bits are allocated starting at
the lowest word in the set then in the lowest bit within that word.
Files
-----
Files are stored as single words containing a pointer to a
data structure within the library. This structure is compatible with
the C structure FILE. This allows Pascal file variables to be used in
calls to C file handling functions.
Pointers
--------
Pointers are stored in single words which address the object pointed
to. The value 0 is used to denote the Nil pointer.
Writing relocatable modules in Pascal
=====================================
To write a module using Pascal you will need to use the CMHG tool
provided with ANSI C Release 4. This tool construct module entry
veneers for C or Pascal code (or any APCS-R conformant code). The
CMHG tool is documented in the chapter "How to write relocatable
modules in C" in the ANSI C manual.
Pascal code to be included in a module must be compiled with the
Module option enabled (-zm from the command line).
Procedures or function which are referenced by the CMHG veneers must
be declared extern.
Pascal code to be included in a module must be linked with the library
'pmodlib' instead of the library 'plib'. This library may be found in
<!PC>.o. The code must also be linked with the shared C library stubs
rather than the unshared ANSILib.
The CMHG entry veneers and Pascal declarations are given below. Note
that each Pascal procedure function requires a declaration and a
definition, just like a forward declaration in standard Pascal but
with the keyword 'extern' substituted for 'forward'.
type _kernel_swi_regs = array[0..9] of integer;
Run entry
---------
module-is-runnable:
No pascal declaration. The run entry of the module will call the
mainline of you Pascal program. The arguments 'argc' and 'argv' may be
accessed through the library functions 'argc' and 'argv'.
Initialisation entry
--------------------
initialisation-code: user_init
function user_init(cmd_tail : string;
podule_base : integer;
pw : pointer) : error; extern;
Finalisation entry
------------------
Finalisation entries are handled by registering a function with the C
library function 'atexit'. The registed function is called when the
module dies. The declarations for 'atexit' and the exit handler are as
follows:
Type atexit_handler = ^procedure exit_handler;
function atexit(exit_handler : atexit_handler) : integer; extern;
procedure exit_handler;
...
Service calls
-------------
service-call-handler: sc_handler <number> <number> ...
procedure sc_handler(service_number : integer;
var r : _kernel_swi_regs;
pw : pointer); extern;
Help and command entries
------------------------
command-keyword-table: cmd_handler <command-description>
function cmd_handler(arg_string : string;
argc : integer;
cmd_no : integer;
pw : pointer) : error; extern;
SWI handler
-----------
swi-handler-code: swi_handler
function swi_handler(swi_no : integer;
var r : _kernel_swi_regs;
pw : pointer) : error; extern;
SWI decoding code
-----------------
swi-decoding-code: swi_decoder
procedure swi_decode(var r : _kernel_swi_regs;
pw : pointer); extern;
IRQ handlers
------------
irq-handlers: entry_name/handler_name
procedure entry_name; extern;
function handler_name(var r : _kernel_swi_regs;
pw : p[ointer); extern;